package com.joyxuan.weixin;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.joyxuan.common.info.weixin.WeixinHelper;
import com.joyxuan.common.info.weixin.form.*;
import com.joyxuan.common.utile.*;
import com.joyxuan.core.wechat.dao.WechatActivityDao;
import com.joyxuan.core.wechat.dao.WechatUserDao;
import com.joyxuan.core.wechat.dto.ArticleDto;
import com.joyxuan.core.wechat.dto.PicTextDto;
import com.joyxuan.core.wechat.po.Introduce;
import com.joyxuan.core.wechat.po.WechatActivity;
import com.joyxuan.core.wechat.po.WechatUser;
import com.joyxuan.core.wechat.service.IntroduceService;
import com.joyxuan.core.wechat.service.WechatUserService;
import com.joyxuan.weixin.mp.TokenGetter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

@Controller
public class WXController extends CommonController {

	public static final ObjectMapper mapper = new ObjectMapper();

	@Autowired
	private WechatUserService wechatUserService;

	@Autowired
	private WechatActivityDao wechatActivityDao;
	@Autowired
	private WechatUserDao wechatUserDao;

	@Autowired
	private IntroduceService introduceService;

	/**
	 * 微信事件处理
	 * 
	 * @param request
	 */
	@RequestMapping("/weixinMessageProcessCenter")
	@ResponseBody
	public String weixinMessageProcessCenter(HttpServletRequest request, HttpServletResponse response) {
		try {
			String echostr = request.getParameter("echostr");
			if (StringUtils.isNotEmpty(echostr)) {
				weixinCheckTicket(request, response);
				return null;
			}
			Object weixinEventObject = null;
			String weixinEventType = null;
			// Map<String, String> map = parseHttpRequestXmlParamToMap();
			InputStream inputStream = request.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
			inputStream.close();
			String xmlStr = sb.toString();
			xmlStr = StringUtils.trim(xmlStr);
			LogUtil.debug(xmlStr);
			Document doc = DocumentHelper.parseText(xmlStr);
			Map<String, Object> map = XmlUtils.Dom2Map(doc);
			if (map == null) {
				return null;
			}
			String json = JsonUtils.object2Json(map);
			LogUtil.debug("微信事件参数：" + json);
			WeixinInfForm weixinInfo = (WeixinInfForm) JsonUtils.json2Object(json, WeixinInfForm.class);
			String touser = null;// WeixinHelper.config.context(weixinInfo.getToUserName());
			if ("event".equalsIgnoreCase(weixinInfo.getMsgType())) {
				if ("subscribe".equalsIgnoreCase(weixinInfo.getEvent())) {
					weixinEventObject = new WeixinEventSubscribeForm(touser, weixinInfo.getFromUserName(),
							weixinInfo.getCreateTime().longValue(), weixinInfo.getEventKey(), weixinInfo.getTicket());
					weixinEventType = "wxOnEventSubscribe";

				} else if ("unsubscribe".equalsIgnoreCase(weixinInfo.getEvent())) {
					weixinEventObject = new WeixinEventUnSubscribeForm(touser, weixinInfo.getFromUserName(),
							weixinInfo.getCreateTime().longValue());
					weixinEventType = "wxOnEventUnSubscribe";
				} else if ("scan".equalsIgnoreCase(weixinInfo.getEvent())) {
					weixinEventObject = new WeixinEventScanForm(touser, weixinInfo.getFromUserName(),
							weixinInfo.getCreateTime().longValue(), weixinInfo.getEventKey(), weixinInfo.getTicket());
					weixinEventType = "wxOnEventScan";
				}
			} else if ("text".equalsIgnoreCase(weixinInfo.getMsgType())) {
				return this.wxOnMessageText(json);

			} else if ("image".equalsIgnoreCase(weixinInfo.getMsgType())) {
				weixinEventObject = new WeixinMessageImageForm(touser, weixinInfo.getFromUserName(),
						weixinInfo.getMsgId(), weixinInfo.getCreateTime().longValue(), weixinInfo.getMediaId(),
						weixinInfo.getPicUrl());
				weixinEventType = "wxOnMessageImage";
			}
			if (weixinEventType != null) {
				String postJson = JsonUtils.object2Json(weixinEventObject);
				switch (weixinEventType) {
				case "wxOnEventSubscribe":
					wxOnEventSubscribe(request, postJson); //公众号关注
					break;
				case "wxOnEventUnSubscribe":

					break;
				case "wxOnEventScan":
					wxOnEventScan(request, postJson); // 处理扫码
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
		return null;
	}

	/**
	 * 处理扫码事件
	 * 
	 * @param request
	 */
	private void wxOnEventScan(HttpServletRequest request, String json) {
		LogUtil.debug("处理微信扫码事件");
		LogUtil.debug(json);
		 WeixinEventSubscribeForm eventSubscribeForm = (WeixinEventSubscribeForm) JsonUtils.json2Object(json,
				WeixinEventSubscribeForm.class);
		LogUtil.debug(eventSubscribeForm);
		if (StringUtils.isNotBlank(eventSubscribeForm.getEventKey())) {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("openid", eventSubscribeForm.getOpenid());
			params.put("activityNo", eventSubscribeForm.getEventKey());
			WechatUser wechatUser = wechatUserDao.findUniqResult(params);
			if (null == wechatUser) {
				wechatUser = new WechatUser();
				wechatUser.setOpenid(eventSubscribeForm.getOpenid());
				wechatUser.setActivityNo(Integer.valueOf(eventSubscribeForm.getEventKey()));
				wechatUser.setSubscribeTime(eventSubscribeForm.getCreateTime());
				wechatUserService.insert(wechatUser);
				final WechatActivity activity = wechatActivityDao.getById(eventSubscribeForm.getEventKey());
				// 推送文本消息
				ThreadUtil.submit(new Runnable() {
					public void run() {
						WeixinHelper.messages.sendTextMsg(TokenGetter.getAccessToken(), eventSubscribeForm.getOpenid(),
								"您已成功参与【" + activity.getActivityName() + "】")
					}
				});
			}
		}
	}

	/**
	 * 关注公众号
	 * 
	 * @param request
	 */
	private void wxOnEventSubscribe(HttpServletRequest request, String json) {
		LogUtil.debug("处理微信关注事件");
		LogUtil.debug(json);
		WeixinEventSubscribeForm eventSubscribeForm = (WeixinEventSubscribeForm) JsonUtils.json2Object(json,
				WeixinEventSubscribeForm.class);
		LogUtil.debug(eventSubscribeForm);
		if (StringUtils.isNotBlank(eventSubscribeForm.getEventKey())) {
			String id = eventSubscribeForm.getEventKey().substring("qrscene_".length(),
					eventSubscribeForm.getEventKey().length());
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("openid", eventSubscribeForm.getOpenid());
			params.put("activityNo", id); // activity_number
			WechatUser wechatUser = wechatUserDao.findUniqResult(params);
			if (null == wechatUser) {
				wechatUser = new WechatUser();
				wechatUser.setOpenid(eventSubscribeForm.getOpenid());
				wechatUser.setActivityNo(Integer.valueOf(id));
				wechatUser.setSubscribeTime(eventSubscribeForm.getCreateTime());
				wechatUserService.insert(wechatUser);
				// 推送文本消息
				WechatActivity activity = wechatActivityDao.getById(id);
				WeixinHelper.messages.sendTextMsg(TokenGetter.getAccessToken(), eventSubscribeForm.getOpenid(),
						"您已成功参与【" + activity.getActivityName() + "】");
			}
		}

	}

	/**
	 * 票据
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping("/weixinCheckTicket")
	public void weixinCheckTicket(HttpServletRequest request, HttpServletResponse response) {
		String echostr = request.getParameter("echostr");
		outputJsonData(echostr, response);
	}

	public static Map<String, String> parseHttpRequestXmlParamToMap() {
		try {
			InputStream inputStream = RequestUtil.getRequest().getInputStream();
			if (inputStream != null) {
				List<String> list = IOUtils.readLines(inputStream, "UTF-8");
				LogUtil.debug(JsonUtils.object2Json(list));
				if (CollectionUtils.isNotEmpty(list))
					return xmlLinesToMap(list);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Map<String, String> xmlLinesToMap(String string) {
		String[] strings = string.split("\r\n|\r|\n");
		List<String> list = Arrays.asList(strings);
		return xmlLinesToMap(list);
	}

	public static Map<String, String> xmlLinesToMap(List<String> strings) {
		Map<String, String> map = new HashMap<String, String>();
		for (String s : strings) {
			s = StringUtils.trim(s);
			s = StringUtils.replace(s, "</xml>", "");
			s = StringUtils.replace(s, "<xml>", "");
			if (StringUtils.isNotEmpty(s)) {
				if (StringUtils.contains(s, "[CDATA[")) {
					String key = s.substring(s.indexOf("<") + 1, s.indexOf(">"));
					String value = s.substring(s.indexOf("[CDATA[") + "[CDATA[".length());
					value = value.substring(0, value.indexOf("]"));
					map.put(key, value);
				} else {
					LogUtil.debug("=========" + s + "===========");
					String key = s.substring(s.indexOf("<") + 1, s.indexOf(">"));
					String value = s.substring(s.indexOf(">") + 1);
					value = value.substring(0, value.indexOf("<"));
					map.put(key, value);
				}
			}
		}
		return map;
	}

	/**
	 * 图文消息处理
	 * 
	 * @return
	 */
	public String wxOnMessageText(String json) {
		Map jsonMap = JsonUtils.json2Object(json, Map.class);
		String openid = (String) jsonMap.get("FromUserName");
		// 只处理指定微信用户的消息
		/*
		 * if (!"oD8cC0za7KJTOzRf09JC03gtqXfk".equals(openid)) { return
		 * "success"; }
		 */
		String content = (String) jsonMap.get("Content");
		Introduce introduce = introduceService.getByName(content);
		if (introduce == null) {
			return "success";
		}

		PicTextDto picTextDto = new PicTextDto();
		picTextDto.setToUserName(openid);
		picTextDto.setFromUserName((String) jsonMap.get("ToUserName"));
		picTextDto.setCreateTime(new Date().getTime());
		picTextDto.setMsgType("news");
		picTextDto.setArticleCount(1);

		ArticleDto articleDto = new ArticleDto();
		articleDto.setTitle(
				introduce.getInviter() + "邀请" + introduce.getName() + introduce.getAppellation() + "参加链动开业庆典！");
		articleDto.setDescription("与享选同行，共同迎接链动科技开业庆典的到来");
		articleDto.setPicUrl(this.getSystemPath() + "resources/img/introduce/joyxuan.png");
		articleDto.setUrl(this.getSystemPath() + "invite?id=" + DesUtil.encrypt(introduce.getId()));

		List<ArticleDto> articleDtos = new ArrayList<>();
		articleDtos.add(articleDto);

		picTextDto.setArticles(articleDtos);

		StringBuilder resp = new StringBuilder(300);
		resp.append("<xml>");
		resp.append("<ToUserName>" + picTextDto.getToUserName() + "</ToUserName>");
		resp.append("<FromUserName>" + picTextDto.getFromUserName() + "</FromUserName>");
		resp.append("<CreateTime>" + picTextDto.getCreateTime() + "</CreateTime>");
		resp.append("<MsgType>" + picTextDto.getMsgType() + "</MsgType>");
		resp.append("<ArticleCount>" + picTextDto.getArticleCount() + "</ArticleCount>");
		resp.append("<Articles>");

		for (ArticleDto dto : picTextDto.getArticles()) {
			resp.append("<item>");
			resp.append("<Title>" + dto.getTitle() + "</Title>");
			resp.append("<Description>" + dto.getDescription() + "</Description>");
			resp.append("<PicUrl>" + dto.getPicUrl() + "</PicUrl>");
			resp.append("<Url>" + dto.getUrl() + "</Url>");
			resp.append("</item>");
		}

		resp.append("</Articles>");
		resp.append("</xml>");

		return resp.toString();
	}

	@RequestMapping("invite")
	public String invite(String id, Model model) {
		id = DesUtil.decrypt(id);// 将id解密
		Introduce introduce = introduceService.getById(Long.valueOf(id));
		model.addAttribute("name", introduce.getName());
		model.addAttribute("appellation", introduce.getAppellation());
		model.addAttribute("inviter", introduce.getInviter());
		return "introduce";
	}
}
